package ldh.maker.controller;

import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.layout.Pane;
import ldh.maker.code.SpringCloudCreateCode;
import ldh.maker.util.DialogUtil;
import ldh.maker.util.FileUtil;
import ldh.maker.util.UiUtil;
import ldh.maker.vo.EurekaServerParam;
import ldh.maker.vo.TreeNode;
import org.controlsfx.control.StatusBar;
import org.controlsfx.validation.Severity;
import org.controlsfx.validation.ValidationSupport;
import org.controlsfx.validation.Validator;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Optional;
import java.util.ResourceBundle;

public class SpringCloudBuilderController implements Initializable {

    ValidationSupport validationSupport = new ValidationSupport();

    private SpringCloudCreateCode springCloudCreateCode = new SpringCloudCreateCode();

    @FXML Button showCreateEurekaServerBtn;
    @FXML Pane eurekaServerPane;
    @FXML Button createEurekaServerBtn;
    @FXML TextField esProjectPackageTextFiled;
    @FXML TextField esNum;
    @FXML TextField esPort;
    @FXML TextField esHost;

    @FXML Button runEurekaServerBtn;
    @FXML Button createZuulBtn;
    @FXML Button createConfigServerBtn;

    @FXML Pane settingPane;

    @FXML StatusBar statusBar;

    public void showEurekaServerAction(ActionEvent actionEvent) {
        UiUtil.hideChildren(settingPane);
        eurekaServerPane.setVisible(true);
    }

    public void createEurekaServerAction(ActionEvent actionEvent) {
        if (validationSupport.isInvalid()) {
            DialogUtil.show(Alert.AlertType.ERROR, "参数错误", "请按照要求填写");
            return;
        }

        EurekaServerParam eurekaServerParam = buildEurekaServerParam();

        Task<Void> task = new Task() {

            @Override
            protected Object call() throws Exception {
                createEurekaServerBtn.setDisable(true);
                springCloudCreateCode.createEurekaServer(eurekaServerParam);
                return null;
            }
        };
        task.setOnSucceeded(e->{
            Platform.runLater(()->{
                createEurekaServerBtn.setDisable(false);
                DialogUtil.show(Alert.AlertType.INFORMATION, "生成成功", "代成功码生成");
            });
        });
        task.setOnFailed(e->{
            Platform.runLater(()->{
                createEurekaServerBtn.setDisable(false);
                DialogUtil.show(Alert.AlertType.INFORMATION, "生成成功", "代成功码生成");
            });
        });
        new Thread(task).start();
    }

    public void runEurekaServerAction(ActionEvent actionEvent) {
        runEurekaServerBtn.setDisable(true);
        packageCode(SpringCloudCreateCode.EurekaServer, "eureka-server");
    }

    public void createZuulAction(ActionEvent actionEvent) {
        Task<Void> task = new Task() {

            @Override
            protected Object call() throws Exception {
                createZuulBtn.setDisable(true);
                springCloudCreateCode.createZuul();
                return null;
            }
        };
        task.setOnSucceeded(e->{
            Platform.runLater(()->{
                createZuulBtn.setDisable(false);
                DialogUtil.show(Alert.AlertType.INFORMATION, "生成成功", "代成功码生成");
            });
        });
        task.setOnFailed(e->{
            Platform.runLater(()->{
                createZuulBtn.setDisable(false);
                DialogUtil.show(Alert.AlertType.INFORMATION, "生成成功", "代成功码生成");
            });
        });
        new Thread(task).start();
        
    }

    public void createConfigServerAction(ActionEvent actionEvent) {
        Task<Void> task = new Task() {

            @Override
            protected Object call() throws Exception {
                createConfigServerBtn.setDisable(true);
                springCloudCreateCode.createConfigServer();
                return null;
            }
        };
        task.setOnSucceeded(e->{
            Platform.runLater(()->{
                createConfigServerBtn.setDisable(false);
                DialogUtil.show(Alert.AlertType.INFORMATION, "生成成功", "代成功码生成");
            });
        });
        task.setOnFailed(e->{
            Platform.runLater(()->{
                createConfigServerBtn.setDisable(false);
                DialogUtil.show(Alert.AlertType.INFORMATION, "生成成功", "代成功码生成");
            });
        });
        new Thread(task).start();
    }

    private void packageCode(String projectName, String fileName) {
        String path = FileUtil.getSourceRoot();
        String codeRoot= path + "code/springcloud/" + projectName;
        Task<Void> task = new Task<Void>() {
            @Override protected Void call() throws Exception {
                updateMessage("开始编译代码");
                try {
                    String cmd = "cmd /k cd " + codeRoot + " && mvn clean package -Pdev";
                    System.out.println("mvn command:" + cmd);
                    Process process = Runtime.getRuntime().exec(cmd);
                    int i = 1000;
                    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                    while(process.isAlive()) {
                        Thread.sleep(200);
                        String line = reader.readLine();
                        if (line == null || line.contains("Finished") || line.contains("BUILD SUCCESS")) {
                            System.out.println("end!!!!!!!!!!!!!!!!!!!!!!!");
                            process.destroy();
                            break;
                        } else if (line != null && line.contains("error")) {
                            System.out.println("error!!!!!!!!!!!!!!!!!!!!!!");
                            process.destroy();
                            break;
                        } else {
                            System.out.println("line:" + line);
                            updateMessage(reader.readLine());
                            updateProgress(i, 200000);
                            i+=200;
                        }
                    }
                    updateProgress(300000, 300000);
                    done();
                    reader.close();
                } catch(Exception e) {
                    e.printStackTrace();
                }
                return null;
            }
        };

        UiUtil.STATUSBAR.textProperty().bind(task.messageProperty());
        UiUtil.STATUSBAR.progressProperty().bind(task.progressProperty());

        task.setOnSucceeded(event -> {
            UiUtil.STATUSBAR.textProperty().unbind();
            UiUtil.STATUSBAR.progressProperty().unbind();

            runCode(projectName, fileName);
        });

        new Thread(task).start();
    }

    private void runCode(String projectName, String fileName) {
        String path = FileUtil.getSourceRoot();
        String codeRoot= path + "code/springcloud/" + projectName + "/target";
        String file = fileName + "-1.0.war";
        File targetFile = new File(file);
        if (!targetFile.exists()) {
            file = fileName + "-1.0.jar";
        }
        runProject(codeRoot, file);
    }

    private void runProject(String dir, String file) {
        String cmd = "cmd /c start java -jar " + dir + "//" + file;
        Task<Void> task = new Task<Void>() {
            @Override protected Void call() throws Exception {
                updateMessage("开始运行代码");
                Process process = Runtime.getRuntime().exec(cmd);
                process.waitFor();
                Thread.sleep(1000);
                updateProgress(300000, 300000);
                done();
                return null;
            }
        };

        UiUtil.STATUSBAR.textProperty().bind(task.messageProperty());
        UiUtil.STATUSBAR.progressProperty().bind(task.progressProperty());

        task.setOnSucceeded(event -> {
            UiUtil.STATUSBAR.textProperty().unbind();
            UiUtil.STATUSBAR.progressProperty().unbind();
        });

        new Thread(task).start();
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        UiUtil.STATUSBAR = statusBar;

        validationSupport.registerValidator(esProjectPackageTextFiled, Validator.createEmptyValidator("项目路径不能为空"));
        validationSupport.registerValidator(esNum,Validator.createRegexValidator("Eureka Server集群个数", "^([0-9]{0,1})+$", Severity.ERROR));
        validationSupport.registerValidator(esPort, Validator.createRegexValidator("Eureka Server端口", "^([0-9]{0,1})+$", Severity.ERROR));
        validationSupport.registerValidator(esHost, Validator.createEmptyValidator("Eureka Server域名"));
    }

    private EurekaServerParam buildEurekaServerParam() {
        EurekaServerParam eurekaServerParam = new EurekaServerParam();
        eurekaServerParam.setProjectPackage(esProjectPackageTextFiled.getText().trim());
        eurekaServerParam.setNum(Integer.parseInt(esNum.getText().trim()));
        eurekaServerParam.setPort(Integer.parseInt(esPort.getText().trim()));
        eurekaServerParam.setHost(esHost.getText().trim());
        return eurekaServerParam;
    }
}
